/**
 * com.monte.util.IDCardUtils.java
 * create by FengMy from 2013
 */
package com.monte.util;

/**
 * @描述:
 *	  号码的结构和表示形式 
 *	 1、号码的结构
 *	 公民身份号码是特征组合码，由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为：六位数字地址码，八位数字出生日期码，三位数字顺序码和一位数字校验码。
 *	 2、地址码
 *	 表示编码对象常住户口所在县(市、旗、区)的行政区划代码，按GB/T2260的规定执行。
 *	 3、出生日期码
 *	 表示编码对象出生的年、月、日，按GB/T7408的规定执行，年、月、日代码之间不用分隔符。
 *	 4、顺序码
 *	 表示在同一地址码所标识的区域范围内，对同年、同月、同日出生的人编定的顺序号，顺序码的奇数分配给男性，偶数分配给女性。
 *	 5、校验码
 *	 （1）十七位数字本体码加权求和公式
 *	 S = Sum(Ai * Wi), i = 0, ... , 16 ，先对前17位数字的权求和
 *	 Ai:表示第i位置上的身份证号码数字值
 *	 Wi:表示第i位置上的加权因子 Wi = mod(power(2,(i-1)),11),i=18,17,16,...,3,2
 *	 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
 *	 （2）计算模
 *	 Y = mod(S, 11)        
 *	 （3）通过模得到对应的校验码
 *	 Y: 0 1 2 3 4 5 6 7 8 9 10
 *	 校验码: 1 0 X 9 8 7 6 5 4 3 2
 *	 四、举例如下：
 *	 北京市朝阳区: 11010519491231002X
 *	 广东省汕头市: 440524188001010014
 * @author FengMy
 * @since 2013-3-18
 */
public class IDCardUtils {
	/**
	 * 15位身份证号码转化为18位的身份证。如果是18位的身份证则直接返回，不作任何变化。
	 * 
	 * @param idCard
	 *            ,15位的有效身份证号码
	 * @return idCard18 返回18位的有效身份证
	 */
	public static String idCard15to18(String idCard) {
		idCard = idCard.trim();
		StringBuffer idCard18 = new StringBuffer(idCard);
		// 加权因子
		// int[] weight = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
		// 校验码值
		char[] checkBit = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3',
				'2' };
		int sum = 0;
		// 15位的身份证
		if (idCard != null && idCard.length() == 15) {
			idCard18.insert(6, "19");
			for (int index = 0; index < idCard18.length(); index++) {
				char c = idCard18.charAt(index);
				int ai = Integer.parseInt(new Character(c).toString());
				// sum = sum+ai*weight[index];
				// 加权因子的算法
				int Wi = ((int) Math.pow(2, idCard18.length() - index)) % 11;
				sum = sum + ai * Wi;
			}
			int indexOfCheckBit = sum % 11; // 取模
			idCard18.append(checkBit[indexOfCheckBit]);
		}

		return idCard18.toString();
	}

	/**
	 * 转化18位身份证位15位身份证。如果输入的是15位的身份证则不做任何转化，直接返回。
	 * 
	 * @param idCard
	 *            18位身份证号码
	 * @return idCard15
	 */
	public static String idCard18to15(String idCard) {
		idCard = idCard.trim();
		StringBuffer idCard15 = new StringBuffer(idCard);
		if (idCard != null && idCard.length() == 18) {
			idCard15.delete(17, 18);
			idCard15.delete(6, 8);
		}
		return idCard15.toString();

	}
}
